package de.zefania.api.impl;

import java.io.File;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;

import org.xml.sax.SAXException;

import de.zefania.api.Position;


/**
 * Class to save the position of a bible vers or a range of verses 
 * @author Thomas
 *
 */
public class PositionImpl implements Position {
	private int bnumber1;
	private int bnumber2;
	private int cnumber1;
	private int cnumber2;
	private int vnumber1;
	private int vnumber2;
	public static enum positionType { MSCOPE, HUMAN }
	
	/**
	 * specifies a range of bible verses
	 * b1, c1 and v1 define the first vers (booknumber, chapter, vers) in this range
	 * b2, c2 and v2 define the last vers (booknumber, chapter, vers) in this range
	 * @param b1
	 * @param b2
	 * @param c1
	 * @param c2
	 * @param v1
	 * @param v2
	 */	
	public PositionImpl(int b1,int b2,int c1,int c2,int v1,int v2) {
		int h; // hilfsvariable
		// einzelne angaben nach gr��e sortieren
		if (b1>b2) { h=b1; b1=b2; b2=h;	}
		if (c1>c2) { h=c1; c1=c2; c2=h;	}
		if (v1>v2) { h=v1; v1=v2; v2=h;	}
		bnumber1 = b1;
		cnumber1 = c1;
		vnumber1 = v1;
		bnumber2 = b2;
		cnumber2 = c2;
		vnumber2 = v2;
	}
	
	/**
	 * specifies a single vers defined by booknumber (b), chapter(c) and vers (v)
	 * @param b1
	 * @param c1
	 * @param v1
	 */
	public PositionImpl(final int b,final int c,final int v) {
		bnumber1 = b;		
		cnumber1 = c;
		vnumber1 = v;
		bnumber2 = b;		
		cnumber2 = c;
		vnumber2 = v;
	}
	
	public PositionImpl(final String posString, final positionType type) throws JfaniaException {
		switch (type) {
		case MSCOPE:
			parseMscope(posString);
			break;
		case HUMAN:
			parseHumanString(posString);
			break;
		default:
			break;
		}
	}
	
	private void parseHumanString(final String humanReadable) {
		String bookRegex = "(\\d?)\\.?\\s*([a-zA-Z������ ]+)\\.?";
		String chapterRegex = "(\\d{1,3})[-]?(\\d{1,3})?";
		String versRegex = "(\\d{1,3})[-]?(\\d{1,3})?";	
		String regex = "^("+bookRegex+")\\s*("+chapterRegex+")?\\s*[,]?\\s*("+versRegex+")?";
		Pattern pattern = Pattern.compile(regex);		
		Matcher matcher = pattern.matcher(humanReadable);
		String bookname="";		
		String chapter1="";
		String chapter2="";		
		String vers1="";
		String vers2="";		
		
		while (matcher.find()) {
			bookname = (matcher.group(2)+matcher.group(3)).trim();
			chapter1 = matcher.group(5);
			chapter2 = matcher.group(6);
			vers1 = matcher.group(8);
			vers2 = matcher.group(9);
		}
		if(chapter1==null) chapter1 = "1";
		if(chapter2==null) chapter2 = chapter1;	
		if(vers1==null) vers1 = "1";
		if(vers2==null) vers2 = vers1;
		int bnumber = 0;		
		BookNamesHandler bhandler;
		try {
			bhandler = new BookNamesHandler(new File("modules/bnames.xml"));
			//TODO Dateiname String ersetzen
			//bhandler.getBookNameSet("german");
			bnumber = bhandler.getBookNumber(bookname); 
			System.out.println("Booknumber: "+bnumber);			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (XPathExpressionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		bnumber1 = bnumber;
		cnumber1 = Integer.valueOf(chapter1);
		vnumber1 = Integer.valueOf(vers1);
		bnumber2 = bnumber;
		cnumber2 = Integer.valueOf(chapter2);
		vnumber2 = Integer.valueOf(vers2);
	}
	
	/**
	 * defines the position by a string given in the mscope format
	 * (see http://wp1066500.wp101.webpack.hosteurope.de/zef/content/view/33/47/ for details) 
	 * @param mscope
	 * @throws Exception
	 */
	private void parseMscope(final String mscope) throws JfaniaException {
		String[] parts = mscope.split(";");
		
		if (parts.length>0) {
			String[] books = parts[0].split("-");
			bnumber1 = Integer.parseInt(books[0]);			
			bnumber2 = (books.length==2) ? Integer.parseInt(books[1]) : Integer.parseInt(books[0]);
			if (bnumber1 > bnumber2) {
				int h = bnumber1; bnumber1 = bnumber2; bnumber2 = h;
			}
		} else {
			throw new JfaniaException("Invalid Mscope");			
		}
		
		if (parts.length>1) {
			String[] chapters = parts[1].split("-");
			cnumber1 = Integer.parseInt(chapters[0]);
			cnumber2 = (chapters.length==2) ?Integer.parseInt(chapters[1]) : Integer.parseInt(chapters[0]);
			if (cnumber1 > cnumber2) {
				int h = cnumber1; cnumber1 = cnumber2; cnumber2 = h;
			}
		}
		
		if (parts.length>2) {
			String[] verses = parts[2].split("-");
			vnumber1 = Integer.parseInt(verses[0]);
			vnumber2 = (verses.length==2) ? Integer.parseInt(verses[1]) : Integer.parseInt(verses[0]);
			if (vnumber1 > vnumber2) {
				int h = vnumber1; vnumber1 = vnumber2; vnumber2 = h;
			}
		}		
	}
		
	public final int b1() { 
		return bnumber1;
	}
	
	public final int b2() {
		return bnumber2;
	}
	
	public final int c1() {
		return cnumber1;
	}
	
	public final int c2() {
		return cnumber2;
	}
	
	public final int v1() {
		return vnumber1;
	}
	
	public final int v2() {
		return vnumber2;
	}	
	
	public final String toMscope() {
		return b1()+"-"+b2()+";"+c1()+"-"+c2()+";"+v1()+"-"+v2();
	}
}
